package com.codemonkey.lq.common.bean;

import java.io.Serializable;

/**
 * ReturnValue的简写
 * @reference
 * 		1. 和以下链接不谋而合, 本人更看中对异常和错误信息处理, 而作者使用了泛型来对返回值进行约束(经历了.NET的泛型之后,实在对这Java的泛型无感)
 * 		1. https://zhuanlan.zhihu.com/p/28717374  <br>
 * 		2. https://zhuanlan.zhihu.com/p/28708259 <br>
 * 		3. https://zhuanlan.zhihu.com/p/28717374 
 * 		3. ResultBean/PageResultBean是controller专用的，不允许往后传！
 * @author LQ
 *
 * @note
 * <ul>
 * 	 <li>这个RV的可查的初始版本为2016-7-7(因为svn迁移过版本库,导致重新导入,使得之前的时间无法追溯) 而我发现华为主管的文章是在2017年8月份</li>
 * 	 <li>因为时间,精力以及最重要的论证(没有可相互商量的人员),不被重视,加上自身的不自信等多重问题导致此类没有被大范围启用.</li>
 * 	 <li>现在终于在知乎找到一篇华为主管写的经验之谈,让本人终于坚定了此类的必要性与正确性.</li>
 * 	 <li>时间凭证参见gitRepository\notes\blog\images\rv_origin.png</li>
 * </ul> 
 * 
 */
public final class RV<TResult> implements Serializable {
	private static final long serialVersionUID = 1L;

	public static final int SUCCESS = 0;

	public static final int FAIL = 1;

	public static final int NO_PERMISSION = 2;

	private String msg = "success";

	private int code = SUCCESS;

	private TResult data;

	private RV() {
		super();
	}

	private RV(TResult data) {
		super();
		this.data = data;
	}

	private RV(Throwable e) {
		super();
		this.msg = e.toString();
		this.code = FAIL;
	}
	
	// ------------------- 《Effective Java》 第一条 P4
	public static <TResult> RV<TResult> of(){
		return new RV<TResult>();
	}
	
	public static <TResult> RV<TResult> of(TResult data){
		return new RV<TResult>(data);
	}
	
	@SuppressWarnings("unchecked")
	public static RV of(Throwable e){
		return new RV(e);
	}

	// ------------------- Props
	public String getMsg() {
		return msg;
	}

	public void setMsg(String msg) {
		this.msg = msg;
	}

	public int getCode() {
		return code;
	}

	public void setCode(int code) {
		this.code = code;
	}

	public TResult getData() {
		return data;
	}

	public void setData(TResult data) {
		this.data = data;
	}	
}

// --------------------------------------------------------------- 备份; 2017-09-18
//public final class RV {
//	private final boolean isSuccess;
//	private final String errorMsg;
//	private final Object data;
//
//	public Object getData() {
//		return data;
//	}
//
//	private RV(boolean isSuccess, String errorMsg, Object data) {
//		super();
//		this.isSuccess = isSuccess;
//		this.errorMsg = errorMsg;
//		this.data = data;
//	}
//
//	/**
//	 * @param data 将要返回的相关数据
//	 * @return
//	 */
//	public static RV of(Object data) {
//		return of(true, null, data);
//	}
//
//	/**
//	 * @param errorMsg 返回的错误信息.因为of(Object data)的存在,所以向of传递null参数时,会调用这个方法.而我们的本意应该是上面那个of(Object data).
//	 * 	可以考虑强制转型来调用
//	 * @return
//	 */
//	public static RV of(String errorMsg) {
//		//如果调用者传递null时,会走这个方法.而不是上面那个Object类型的参数.
//		if (StringHelper.isEmpty(errorMsg)) {
//			return of((Object) errorMsg);
//		}
//		return of(false, errorMsg, null);
//	}
//
//	private static final RV ONLY_SUCCESS_FLAG_RV = of(true, null, null);
//
//	/**
//	 * @return 代表本次所有操作全部正确完成.
//	 */
//	public static RV ofOnlySuccess() {
//		return ONLY_SUCCESS_FLAG_RV;
//	}
//
//	public static RV of(boolean isSuccess, String errorMsg, Object data) {
//		return new RV(isSuccess, errorMsg, data);
//	}
//
//	public boolean isSuccess() {
//		return isSuccess;
//	}
//
////	@Override
////	public String toString() {
////		return toJSONString();
////	}
//
////	/**
////	 * @return status : 0表示成功;1表示失败
////	 *         msg    : 失败时的错误信息
////	 *         data   : 成功时返回的数据
////	 */
////	public String toJSONString() {
////		JSONObject object = new JSONObject();
////		object.put("status", isSuccess ? 0 : 1);
////		object.put("msg", errorMsg);
////		object.put("data", data);
////		return object.toJSONString();
////	}
//
//	/************************************************************************************************************
//	 * 构建者模式
//	 
//	public static class Builder {
//	private boolean status = true;
//	private String msg = StringUtils.EMPTY;
//	private Object data = null;
//
//	public Builder status(boolean status) {
//	    this.status = status;
//	    return this;
//	}
//
//	public Builder msg(String msg) {
//	    this.msg = msg;
//	    return this;
//	}
//
//	public Builder data(Object data) {
//	    this.data = data;
//	    return this;
//	}
//
//	public ReturnValue builder() {
//	    return new ReturnValue(this.status, this.msg, this.data);
//	}
//	}
//	
//	 public static void main(String[] args) {
//	String string = new ReturnValue.Builder().status(false).msg("haha").data("this").builder().toString();
//	System.out.println(string);
//	}   
//	*/
//}